home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hardcore Visual Basic 5.0 (2nd Edition)
/
Hardcore Visual Basic 5.0 - Second Edition (1997)(Microsoft Press).iso
/
Source
/
Sieve
/
SIEVEMFC
/
SIEVE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-02
|
5KB
|
190 lines
// Sieve.cpp : implementation file
//
#include "stdafx.h"
#include "SieveMFC.h"
#include "Sieve.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSieveMFC
IMPLEMENT_DYNCREATE(CSieveMFC, CCmdTarget)
CSieveMFC::CSieveMFC()
{
EnableAutomation();
// Default size is largest integer
m_af = 0;
SetMaxPrime(32766);
// To keep the application running as long as an OLE automation
// object is active, the constructor calls AfxOleLockApp.
AfxOleLockApp();
}
CSieveMFC::~CSieveMFC()
{
// To terminate the application when all objects created with
// with OLE automation, the destructor calls AfxOleUnlockApp.
AfxOleUnlockApp();
}
void CSieveMFC::OnFinalRelease()
{
// When the last reference for an automation object is released
// OnFinalRelease is called. The base class will automatically
// deletes the object. Add additional cleanup required for your
// object before calling the base class.
CCmdTarget::OnFinalRelease();
}
BEGIN_MESSAGE_MAP(CSieveMFC, CCmdTarget)
//{{AFX_MSG_MAP(CSieveMFC)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_DISPATCH_MAP(CSieveMFC, CCmdTarget)
//{{AFX_DISPATCH_MAP(CSieveMFC)
DISP_PROPERTY_EX(CSieveMFC, "NextPrime", GetNextPrime, SetNotSupported, VT_I2)
DISP_PROPERTY_EX(CSieveMFC, "MaxPrime", GetMaxPrime, SetMaxPrime, VT_I2)
DISP_PROPERTY_EX(CSieveMFC, "Primes", GetPrimes, SetNotSupported, VT_I2)
DISP_FUNCTION(CSieveMFC, "ReInitialize", ReInitialize, VT_EMPTY, VTS_NONE)
DISP_FUNCTION(CSieveMFC, "AllPrimes", AllPrimes, VT_EMPTY, VTS_PVARIANT)
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()
// Note: we add support for IID_IMSieve to support typesafe binding
// from VBA. This IID must match the GUID that is attached to the
// dispinterface in the .ODL file.
// {06CD1DA5-FB34-11CE-AE38-08002B32A778}
static const IID IID_IMSieve =
{ 0x6cd1da5, 0xfb34, 0x11ce, { 0xae, 0x38, 0x8, 0x0, 0x2b, 0x32, 0xa7, 0x78 } };
BEGIN_INTERFACE_MAP(CSieveMFC, CCmdTarget)
INTERFACE_PART(CSieveMFC, IID_IMSieve, Dispatch)
END_INTERFACE_MAP()
// {06CD1DA6-FB34-11CE-AE38-08002B32A778}
IMPLEMENT_OLECREATE(CSieveMFC, "SieveMFC.CSieveMFC", 0x6cd1da6, 0xfb34, 0x11ce, 0xae, 0x38, 0x8, 0x0, 0x2b, 0x32, 0xa7, 0x78)
/////////////////////////////////////////////////////////////////////////////
// CSieveMFC message handlers
short CSieveMFC::GetNextPrime()
{
// Loop until we find a prime or overflow array
m_iCur++;
while (m_af[m_iCur]) {
m_iCur++;
// Array overflow
if (m_iCur > m_iMaxPrime) {
return 0;
}
}
// Cancel multiples of this prime
int i;
for (i = m_iCur + m_iCur; i < m_iMaxPrime; i += m_iCur) {
m_af[i] = 1;
}
// Count and return it
m_cPrime++;
return m_iCur;
}
short CSieveMFC::GetMaxPrime()
{
return m_iMaxPrime;
}
void CSieveMFC::SetMaxPrime(short nNewValue)
{
m_iMaxPrime = nNewValue;
ReInitialize();
}
short CSieveMFC::GetPrimes()
{
return m_cPrime;
}
void CSieveMFC::ReInitialize()
{
if (m_af) {
delete m_af;
}
m_af = new short[m_iMaxPrime];
memset(m_af, 0, sizeof(short) * m_iMaxPrime);
m_iCur = 1;
m_cPrime = 0;
}
void CSieveMFC::AllPrimes(LPVARIANT pv)
{
int i;
long c;
short FAR * af;
SAFEARRAYBOUND asabound[1];
SAFEARRAY FAR * psa;
if ((pv->vt & VT_ARRAY) == 0)
goto AllPrimesError;
psa = (LPSAFEARRAY)(pv->pparray);
if (SafeArrayGetDim(psa) != 1)
goto AllPrimesError;
if (SafeArrayGetLBound(psa, 1, &c) != S_OK)
goto AllPrimesError;
if (c != 0)
goto AllPrimesError;
if (SafeArrayGetUBound(psa, 1, &c) != S_OK)
goto AllPrimesError;
if (c > SHRT_MAX - 1)
goto AllPrimesError;
if (SafeArrayGetElemsize(psa) != sizeof(short))
goto AllPrimesError;
if (SafeArrayAccessData(psa, (void **)&af) != S_OK)
goto AllPrimesError;
m_iMaxPrime = (short)c;
m_cPrime = 0;
for (m_iCur = 2; m_iCur < m_iMaxPrime; m_iCur++) {
if (!af[m_iCur]) {
// Found a prime
for (i = m_iCur + m_iCur; i < m_iMaxPrime; i += m_iCur) {
af[i] = 1; // Cancel its multiples
}
af[m_cPrime] = m_iCur;
m_cPrime++;
}
}
if (SafeArrayUnaccessData(psa) != S_OK)
goto AllPrimesError;
asabound[0].lLbound = 0;
asabound[0].cElements = m_cPrime;
if (SafeArrayRedim(psa, asabound) != S_OK)
goto AllPrimesError;
m_iCur = 1;
return;
AllPrimesError:
AfxThrowOleDispatchException(1, "Invalid array argument");
return;
}